package com.zhangliang.filter;

import com.zhangliang.utils.TPMonitor;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Activate(group = {CommonConstants.CONSUMER})
public class TPMonitorFilter implements Filter, Runnable {

    public TPMonitorFilter() {
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this, 1, 5, TimeUnit.SECONDS);

    }

    private final Map<String, TPMonitor> methodRequests = new ConcurrentHashMap<>();
    private int totalCount = 0;

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
//        System.out.println("-------");
        String methodName = invocation.getMethodName();
        long start = System.currentTimeMillis();
        try {
            return invoker.invoke(invocation);
        } finally {
            int costTime = (int)(System.currentTimeMillis() - start);
//            System.out.print(methodName + " invoke time: " + costTime + "ms --> ");
//            System.out.println(methodName + " invoke time: " + costTime + "ms");

            if (!methodRequests.containsKey(methodName)) {
                methodRequests.put(methodName, new TPMonitor(60));
            }
            methodRequests.get(methodName).offer(costTime);
            ++totalCount;
        }
    }

    @Override
    public void run() {
        System.out.println("\n\n**** request count: " + totalCount + " *****");
        for (String methodName : methodRequests.keySet()) {
            System.out.println("------- " + methodName + " --------");
//            System.out.println(methodRequests.get(methodName));
            System.out.println("TP90: " + methodRequests.get(methodName).getTopPercentile(90));
            System.out.println("TP95: " + methodRequests.get(methodName).getTopPercentile(95));

        }
    }
}
